from utils.misc import JsonSettingsReader
from progressbar import ProgressBar, SimpleProgress, Timer
from utils import dbf
import os
import sys


class Rcz:
    def __init__(self, rootfolder):
        if not os.path.isdir(rootfolder):
            raise Exception("rootfolder is not a folder.")
        else:
            self.rootfolder = rootfolder
        self.reports = {}
        self.settings = None

    def _open_settings(self, path):
        settings_reader = JsonSettingsReader(path)
        self.settings = settings_reader.settings

    def _check_reports_consistency(self):
        """Checks if self.reports are consistent."""
        pass

    def _build_reports(self):
        if not self.settings:
            raise Exception("settings have no been loaded yet!")

        # Clear previous reports:
        print 'Clearing previous reports'
        self.reports.clear()
        file_list = []

        # Get file_list by recursively walking rootfolder:
        for root, sub_folders, files in os.walk(self.rootfolder):
            matching_files = filter(
                lambda f: os.path.splitext(f)[-1].lower() == '.dbf',
                files)
            filenames = map(lambda f: os.path.join(root, f), matching_files)
            file_list.extend(filenames)

        # Read files and show progress:
        print 'Reading files'
        pbar_widgets = ['File ', SimpleProgress(), ' (', Timer(), ')']
        pbar = ProgressBar(widgets=pbar_widgets, maxval=len(file_list)).start()
        for fpos, f in enumerate(file_list):
            try:
                with dbf.Table(filename=f) as table:  # this opens and closes the table when done
                    # Check if the table has any records:
                    if not table:
                        raise Exception("%s are 0 records!" % f)

                    # Get the defined expected field count:
                    field_count = len(self.settings['field']['names'])

                    # Check if the table field count matches the defined field count:
                    if table.field_count != field_count:
                        raise Exception("%s are %d campuri in loc de %d cat sunt definite in setari!" %
                            (f, table.field_count, field_count))

                    # Read table and save record values using field names defined in the settings:
                    for record in table:
                        record_values = {}

                        for col in range(field_count):
                            col_name = self.settings['field']['names'][col]
                            value = record[col]

                            if type(value) == unicode:
                                record_values[col_name] = value.strip()  # remove trailing and ending spaces
                            else:
                                record_values[col_name] = value

                        punct_lucru = record_values['denumire']  # TODO: add these keys to settings.json
                        judet = record_values['judet']
                        # data_start = record_values['data start']
                        # data_stop = record_values['data stop']

                        # Add record values to self.reports after some verification:
                        if punct_lucru in self.reports.keys():
                            if judet in self.reports[punct_lucru].keys():
                                #self.reports[punct_lucru][judet].append(record_values)
                                for rv in self.reports[punct_lucru][judet]:
                                    # Check if the report has been added already:
                                    # if date before etc
                                    pass
                            else:
                                # Adauga record_values pentru judet nou (judet este cheie noua pentru dict):
                                self.reports[punct_lucru][judet] = []
                                self.reports[punct_lucru][judet].append(record_values)
                        else:
                            # Adauga record_values pentru punct_lucru nou si judet nou:
                            self.reports[punct_lucru] = {}
                            self.reports[punct_lucru][judet] = []
                            self.reports[punct_lucru][judet].append(record_values)
            except:
                raise

            pbar.update(fpos)  # show we are done with the another file

        pbar.finish()

    # def filter(self, filtru={}):
    #     print("=> Se filtreaza cu filtrul %s\n" % filtru)
    #     startDateKey = self.settings["coloane"]["coloaneIntervalData"][0]
    #     stopDateKey = self.settings["coloane"]["coloaneIntervalData"][1]
    #     farmacieKey = self.settings["coloane"]["coloanaFarmacie"]
    #     casKey = self.settings["coloane"]["coloanaCas"]
    #     filtrate = []

    #     for report in self.reports:
    #         for record in report:
    #             try:
    #                 if(record[farmacieKey].lower() == filtru[farmacieKey].lower() and
    #                     record[casKey].lower() == filtru[casKey].lower()):
    #                     startDate = filtru[startDateKey]
    #                     stopDate = filtru[stopDateKey]
    #                     reportStartDate = datetime.strptime(record[startDateKey],
    #                         '%Y-%m-%d')
    #                     reportStopDate = datetime.strptime(record[stopDateKey],
    #                         '%Y-%m-%d')
    #                     if(startDate <= stopDate and
    #                         startDate <= reportStartDate <= stopDate and
    #                         startDate <= reportStopDate <= stopDate):
    #                         filtrate.append(record)
    #             except Exception as e:
    #                 print("Eroare '%s' la filtrare: %s" % (type(e).__name__, e))
    #                 print record
    #     return filtrate

if __name__ == '__main__':
    try:
        rcz = Rcz('c:\\Consumuri\\Downloadate')
        rcz._open_settings('settings.json')
        rcz._build_reports()
        sys.stdin.read(1)
    except KeyboardInterrupt as e:
        print("\nExecutia a fost intrerupta la comanda.\n")
        sys.exit(0)
